;(function(){
    App.defineViewModel("#workflow-demo",{
        data:{},
        watch:{},
        methods:{}
    },{
        ready:{
        },
        beforeRender:function () {
            var id = 1;
            var that = this;
            //获取配置文件
            $.get("pres.xml",function (xml) {
                var xml = $(xml);
                var table  = {};

                xml.find("start>transition,fork>transition").each(function (i, o) {
                    var name = $(o).attr("name");
                    var to = $(o).attr("to");
                    table[name] = table[name]||[];
                    table[name].push(to);
                    table[name].type = $(o).get(0).tagName;

                    table[to] = table[to]||[];
                    table[to].parent = table[to].parent||[];
                    table[to].parent.push(name);
                });

                xml.find("sub-process>transition,join>transition").each(function (i, o) {
                    var name = $(o).parent().attr("name");
                    var to = $(o).attr("to");
                    table[name] = table[name]||[];
                    table[name].push(to);
                    table[name].type = $(o).parent().get(0).tagName;

                    table[to] = table[to]||[];
                    table[to].parent = table[to].parent||[];
                    table[to].parent.push(name);
                });

                xml.find("fork").each(function (i, o) {
                    var name = $(o).attr("name");
                    table[name] = table[name]||[];
                    table[name].type = $(o).get(0).tagName;

                    $(o).find(">transition").each(function (index, t) {
                        var to = $(t).attr("name");
                        table[name].push(to);

                        table[to] = table[to]||[];
                        table[to].parent = table[to].parent||[];
                        table[to].parent.push(name);
                    })
                });

                xml.find("end").each(function (i, o) {
                    var name = $(o).attr("name");
                    var to = $(o).attr("to");
                    table[name] = table[name]||[];
                    // table[name].push(to);
                    table[name].type = $(o).get(0).tagName;

                    // table[to] = table[to]||[];
                    // table[to].parent = table[to].parent||[];
                    // table[to].parent.push(name);
                });

                //拿context2D
                var ctx = that.model.$els.canvas.getContext("2d");

                //获取canvas的宽高
                var w = ctx.canvas.width;
                var h = ctx.canvas.height;

                // ctx.canvas.width*=2;
                // ctx.canvas.height*=2;
                //
                // ctx.canvas.style.height = h+"px";
                // ctx.canvas.style.width = w+"px";
                //
                // w*=2;
                // h*=2;

                // ctx.rect(startX+width/2-10,startY+80*(nodeIndex++),20,20);
                // ctx.fill();

                var drawMap = {};

                function drawTree(root,startX,startY,width) {
                    // ctx.rect(startX+width/2-10,startY+80,20,20);
                    // ctx.fill();
                    // if(!table[root].draw){
                    //     //if node has more parent nodes
                    //     var nodes = [];
                    //     Object.keys(table).forEach(function (key) {
                    //         if(table[key].indexOf(root)>-1){
                    //             nodes.push(table[key].draw)
                    //         }
                    //     });
                    //     if(nodes.length>1){
                    //         // ctx.strokeText(root,startX+width*i/2,startY+30)
                    //         //fix x,y,width
                    //         var y=[],x=0;
                    //         nodes.forEach(function (node) {
                    //             if(node) x+=(node.x)
                    //             if(node) y.push(node.y)
                    //         })
                    //         y=Math.max.apply(null,y)
                    //         startX=x;
                    //         startY=y
                    //     }

                    // ctx.font="10px Arial";
                    // ctx.fillText(root,startX+width/2-10,startY+30)
                    var size = 1;
                    function lookUp(node) {
                        if(table[node].parent.length>0){
                            if(table[table[node].parent[0]].type=="fork"){
                                size--;
                                if(size==0){
                                    return table[table[node].parent[0]].draw;
                                }else{
                                    return lookUp(table[node].parent[0]);
                                }
                            }else if(table[table[node].parent[0]].type=="join"){
                                size++;
                            }
                            return lookUp(table[node].parent[0]);
                        }
                    }

                    var info = {
                        node:root,
                        x:startX+width/2,
                        y:startY+30,
                        w:width,
                        type:table[root].type
                    };

                    if(table[root].type=="join"){
                        var tmp= lookUp(root)
                        width = tmp.w
                        startX = tmp.x-tmp.w/2
                        info.x = tmp.x
                        info.w = tmp.w
                    }


                    drawMap[startY+30] = drawMap[startY+30]||[];
                    drawMap[startY+30].push(info);
                    table[root].draw = info;
                    //     table[root].draw={
                    //         x:startX+width/2-10,
                    //         y:startY+30
                    //     };
                    // }

                    if(table[root]&&table[root].length>0){
                        table[root].forEach(function (t,index) {
                            drawTree(t,startX+width/table[root].length*index,startY+30,width/table[root].length)
                        })
                    }
                }


                drawTree("to 分支 1",0,0,w);

                var pos = {};
                Object.keys(drawMap).reverse().forEach(function (height) {

                    drawMap[height].forEach(function (node,index,arr) {
                        if( pos[node.node]) return;
                        pos[node.node] = true;


                        // ctx.font="10px Arial";
                        // var x =getX(node.node);
                        //
                        // if(node.type!="join"){
                            x = node.x
                        // }
                        //
                        // ctx.fillText(node.node,x,node.y)
                        ctx.fillStyle="#ccc";
                        ctx.fillRect(x-20,node.y,40,20)
                    });
                })

                function getX(name) {
                    var x = 0 ;
                    var size = 0;
                    Object.keys(drawMap).reverse().forEach(function (height) {

                        drawMap[height].forEach(function (node,index,arr) {
                            if(node.node==name){
                                x+=node.x;
                                size++;
                            }
                        });
                    })
                    return x/size;
                }


                // var forks = xml.find("fork");
                //
                // forks.each(function (i, o) {
                //     var trans = $(o).find("transition");
                //
                //     trans.each(function (index, t) {
                //         var sub = xml.find("[name='"+$(t).attr("to")+"']");
                //        if(sub.get(0).tagName=="fork"){
                //            $(t).after(sub)
                //            $(t).replaceWith($("<node></node>"))
                //            console.log(t)
                //        }
                //     })
                //
                // })
                //
                // forks.each(function (i, o) {
                //
                //     $(o).wrap("<split></split>");
                //
                //
                //     var node =$("<node></node>");
                //     node.attr("name",$(o).attr("name"));
                //     var to = id++;
                //     node.attr("to",to);
                //     $(o).before(node.get(0));//add fork's node el
                //
                //
                //
                //
                //
                //
                // })

                // console.log(xml.get(0))
            })


            $.get("config.xml",function (xml) {

                //将配置变成jquery对象，方便取子节点和节点属性
                xml = $(xml);

                //拿context2D
                var ctx = that.model.$els.canvas2.getContext("2d");

                //获取canvas的宽高
                var w = ctx.canvas.width;
                var h = ctx.canvas.height;

                ctx.canvas.width*=2;
                ctx.canvas.height*=2;

                ctx.canvas.style.height = h+"px";
                ctx.canvas.style.width = w+"px";

                w*=2;
                h*=2;

                //先寻找起始节点，假定当前根节点的第一个子元素
                /**
                 * 绘制流程图
                 * @param root 当前绘制的图的根节点，这里有可能是主树，有可能是子树
                 * @param startX 当前绘制的图的起始X坐标
                 * @param startY 当前绘制的图的起始Y坐标
                 * @param width 当前绘制的图的宽度
                 */
                function drawTree(root,startX,startY,width) {

                    //nodeIndex表示竖向上当前已经到第几个节点了
                    var nodeIndex = 0;

                    //获取根节点id
                    var start = root.find("node").get(0).id;

                    //这里的循环实在遍历整个树，如果发现整个树有子树，那么就递归drawTree方法
                    while(true){

                        //拿到节点的jquery对象
                        var node = root.find("#"+start);

                        //循环终止条件，也是递归出口，不存在子节点的时候
                        if(node.size()==0) break;

                        //获取节点id和下一个节点
                        start = node.attr("to");
                        var id = node.attr("id");

                        if(node.get(0).tagName.toLowerCase() == "split"){
                            //当前节点是子树
                            var flow = node.find(">flow");

                            flow.each(function (i, o) {
                                //开始绘制每一颗子树，每一棵子树都是递归出来的
                                drawTree($(o),startX+width/flow.size()*i,startY+80*(nodeIndex),width/flow.size())
                            });

                            //这里是为了找哪个子树有最多的子节点，然后增加树的高度，以便画父树的下一个节点的时候不会被覆盖掉
                            //注意这个nodeIndex的作用域，在递归内部的时候是局部变量所以每个tree都有一个nodeIndex
                            //这一行代码应该是获得子树的最大高度

                            nodeIndex+=calHeight(node);
                        }else{
                            //当前节点不是子树，就绘制节点
                            ctx.rect(startX+width/2-10,startY+80*(nodeIndex++),20,20);
                            ctx.fill();
                            // ctx.strokeStyle = "red";0
                            // ctx.strokeText(id,startX+width/2-10,startY+80*(++nodeIndex));
                            // ctx.stroke()
                        }
                    }
                }

                /**
                 * 计算子树的高度
                 * @param root
                 * @returns {*}
                 */
                function calHeight(root) {
                    var length = root.find(">flow").map(function (index,el) {
                        var els = $(el).find(">node,>split");
                        var size = 0 ;
                        els.each(function (i, o) {
                            if(o.tagName=="node"){
                                size++;
                            }else{
                                size+=calHeight($(o))
                            }
                        });
                        return size;
                    });

                    return Math.max.apply(null,length);

                    // var split = root.find(">flow>split");
                    // if(split.size()>0){
                    //     max+=Math.max.apply(null,root.find(">flow>split").map(function (index,el) {
                    //         return calHeight($(el));
                    //     }))
                    // }
                    //
                    // return max;
                }

                drawTree(xml,0,0,w);
            })
        },
        afterRender:function (){
        },
        beforeUnRender:function (){
        },
        afterUnRender:function (){
        }
    });
})();

